package com.shop.web.aspect;

import com.alibaba.fastjson.JSON;
import com.shop.web.context.WebContext;
import com.shop.web.exception.GCRuntimeException;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.Map;
import java.util.TreeMap;

@Aspect
@Component
public class HttpLogAspect {
    private static final Logger log = LoggerFactory.getLogger("sys.http.log");

    @Autowired
    private HttpServletRequest request;

    /**
     * 切换打印日志
     *
     * @param pjp
     * @return
     * @throws Throwable
     */
    @Around("execution(public * com.*.*.controller.*.*.*(..))")
    public Object doLogger(ProceedingJoinPoint pjp) throws Throwable {
        StringBuffer exceptionMsg = new StringBuffer();
        long startTime = System.currentTimeMillis();
        HttpLogRequestParam params = new HttpLogRequestParam();

        // WebContext
        try {
            params.setClientId(WebContext.getClientId());
            params.setClientType(WebContext.getClientType());
            params.setClientModel(WebContext.getClientModel());
            params.setClientVersion(WebContext.getClientVersion());
            params.setRequestId(WebContext.getRequestId());
            params.setRequestTimestamp(WebContext.getRequestTimestamp());
            params.setRequestIp(WebContext.getRequestIp());
            params.setRequestUri(request.getRequestURI());
        } catch (GCRuntimeException e) {
            //
            throw e;
        } catch (Exception e) {
            log.error("-error-WebContext-", e);
            exceptionMsg.append("-error-WebContext-").append(e.toString());
            throw e;
        }

        // requestHeaders
        try {
            Map<String, String> requestHeaders = new TreeMap();
            Enumeration<String> headerNames = request.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String headerName = headerNames.nextElement();
                requestHeaders.put(headerName, request.getHeader(headerName));
            }
            params.setRequestHeaders(requestHeaders);
            params.setRequestParameters(request.getParameterMap());
        } catch (GCRuntimeException e) {
            //
            throw e;
        } catch (Exception e) {
            log.error("-error-headers/parameters-", e);
            exceptionMsg.append("-error-headers/parameters-").append(e.toString());
            throw e;
        }

        // requestBody
        String requestBody = WebContext.getRequestBody();
        if(StringUtils.isNotBlank(requestBody)) {
            params.setRequestBody(requestBody);
        }

        // response
        Object responseValue = null;
        try {
            responseValue = pjp.proceed(pjp.getArgs());
        } catch (GCRuntimeException e) {
            //
            throw e;
        } catch (Throwable e) {
            log.error("-error-responseValue-", e);
            exceptionMsg.append("-error-responseValue-").append(e.toString());
            throw e;
        } finally {
            long endTime = System.currentTimeMillis();
            long responseTime = endTime - startTime;
            params.setResponseTime(Long.valueOf(responseTime).toString());
            params.setResponseValue(JSON.toJSONString(responseValue));
            params.setExceptionMsg(exceptionMsg.toString());

            // 打印参数
            //log.info(params.toJsonStringRemovingCRLF());
        }

        return responseValue;
    }

}
